﻿#ifndef _FACESELECT_H_
#define _FACESELECT_H_

#include "cv.h"
#include <highgui.h>

#define MAXLEN_OUTDIR 128
#define MAXLEN_FNAME 128
#define MAXLEN_PATH ( MAXLEN_OUTDIR + MAXLEN_FNAME )
#define MAXLEN_RESSTR 512

class CATMFaceSelect
{
public:
	CATMFaceSelect(void);
	virtual ~CATMFaceSelect(void);

	CvSeq* FaceExtract( IplImage* pImage, CvMemStorage* pStorage );


private:
	void ResizeImg( IplImage* imgOrg, IplImage* &imgDes, double dScale );
	//缩放图像: imgOrg为原始图，imgDes为缩放后的图
	//ATTENTION　:　imgDes在函数内进行内存分配
	//缩放关系：
	//imgDes->width = imgOrg->width * dScale
	//imgDes->height = imgOrg->height * dScale
	//ATTENTION	:	imgDes必须释放！！！

	bool transferLocalRc2SceneRc( CvRect* rcInScene, CvRect* rcLocal, CvRect* rcRgn, double dScale );

	bool GetOrgRect( CvRect* rcOrg, const CvRect* rcScale, double dScale );
	//与函数resizeImg配套
	//rcDes为目标框在imgDes图像中的位置
	//本函数将imgDes中的位置rcDes，转化为在imgOrg图像中的位置rcOrg

	bool GetOrgRectSeq( CvSeq* orgFaces, const CvSeq* scaleFaces, double dScale );
	//与函数GetOrgRect相对应

	void InitClass();//Michael Add 20090507
	void ClearImgSeq();
	void ClearImageSeq();
	void ClearFaceSeq();
	void ClearStorageSeq();

	bool InitCascade( const char* cascade_name, CvHaarClassifierCascade* &cascade, CvMemStorage *casMem );
	void ReleaseCascade( CvHaarClassifierCascade* &cascade, CvMemStorage *casMem );
	void ReleaseImageSeq();
	void ReleaseFaceSeq();
	void ReleaseStorageSeq();

	void MultiObjectInitialize();
	void MultiObjectRelease();

	bool initSubFaceFeatureCascade( );
	void releaseSubFaceFeatureCascade( );

	void GetUpperbody( CvRect* pImage, CvSize rcSize, CvRect* pUpperbody);
		IplImage* GetSubImage(IplImage* pOriImage, CvRect roi); /*子图像在函数内创建用完要手动释放*/

	CvMemStorage* m_cvSeqStorage;
	CvSeq* m_cvImageSeq;
	CvHaarClassifierCascade* m_cascade_face;
	CvMemStorage *m_casMem_face;
	CvSeq* m_cvSeqFaceSeq;
	CvMemStorage* m_cvSeqFaceSeqStorage;
	CvSeq* m_cvSeqFaceStorage;
	CvMemStorage* m_cvSeqFaceStorageStorage;

	CvHaarClassifierCascade* m_cascade_eye;//left eye
	CvHaarClassifierCascade* m_cascade_reye;
	CvHaarClassifierCascade* m_cascade_mouth;
	CvMemStorage *m_casMem_eye;
	CvMemStorage *m_casMem_reye;
	CvMemStorage *m_casMem_mouth;
	CvMemStorage* m_storage_subfacefeature;

	double m_dSglBkgProportion; //可能出现的单边背景区域
	double m_dFaceProportion;	//脸部区域在直方图中最少所占的比重
	bool m_bScaleFaceDetection; //脸部检测中是否开启缩放
	double m_dScale; //缩放比例
	double m_dForeheadNoise; //平抑不对称的额发引起的噪声Obsolete
	double m_dUpBkgNoise; //平抑不对称的额发引起的噪声
	double m_dSideBkgNoise; //平抑两侧背景引起的噪声Obsolete
	double m_dEarNoise; //平抑耳朵可能引起的噪声
	int m_iFaceSize; //最小脸部大小
	int m_iSFactorValv; //判断真假脸的阈值
	int m_iSizeWeight; //尺寸权重
	int m_iLightCondition; //光线环境 0-顺光 1-逆光 2-强逆光

	//多人寻优
	CvMemStorage *m_pDiffRectStorage;
	CvMemStorage *m_pDiffJudgeStorage;
	CvSeq *m_sqDiffFaceRect;
	CvSeq *m_sqDiffFaceJudge;
	CvMemStorage *m_pHistStorage;
	CvSeq *m_sqHist;
	CvMemStorage *m_pImgNoStorage;
	CvSeq *m_sqImgNo;

	double m_dFaceChangeRatio;//最大脸与最小脸的尺度比例关系
	CvRect m_rcROI;
	char m_outputDir[MAXLEN_OUTDIR];
	char m_resString[MAXLEN_RESSTR];
	double m_ExRatio_t, m_ExRatio_b, m_ExRatio_l, m_ExRatio_r;

	bool m_bDebugForBkgAna;


public:
	//Michael Add -- 设置类变量的接口
	void SetROI( int x, int y, int width, int height );//如果不调用本函数设置检测区，检测区即为全图
	void SetFaceParas( int iMinFace, double dFaceChangeRatio = 5.0f );//设置脸的大小，iMinFace:最小的脸宽，dFaceChangeRatio：最大脸宽与最小脸宽之间的比例
	void SetDwSmpRatio( double dRatio );//设置降采样率, 如果希望将图像降采样处理，dRatio应小于1.0，该参数默认为0.5，即找脸时将图像长宽均变为原来的0.5倍，以节约搜索时间

	//SetExRatio : 设置输出的图片应在人脸的四个方向扩展多少比例
	//如果人脸框大小保持不变，4个值都应该为0.0f
	void SetExRatio( double topExRatio, double bottomExRatio, double leftExRatio, double rightExRatio );
};

#endif
